angular.js 등의 자바스크립트 MVC 프레임웍을 보면 MVC에 대한 오해가 하나 보인다. 원래 고전적인 MVC에서 말하는 Model은 비즈니스 모델 객체를 말하는 게 아니라 View에 맞는 데이터를 담고 있는 Model이다. 그런데 웹 스타일의 MVC가 더 흥하면서 개념이 약간 바뀌기 시작했는데, 고전적인 MVC로 돌아가려는 자바스크립트 MVC 프레임웍들은 그 개념 변경을 이해하지 못한 상태에서 돌아가는 중이다. 예를 하나 들어보자.
상품 정보가 Product 객체에 담겨 있고 이걸 목록 형태, ListView에 뿌려주고 싶다. 이럴 때 웹 스타일의 MVC가 하는 방식은 이렇다. 컨트롤러에서 사용자의 요청을 받은 다음 뿌려줄 Product 목록을 가져와서 HTML 템플릿으로 된 View에 하나씩 뿌려준다. 이를테면 다음과 같은 식이다.
Controller
def products(request):
products = Product.objects.all()
return render_to_response('products.html', locals())
View
% for product in products:
<li>${product.name}: ${product.price}</li>
% endfor
여기서의 Product는 고전적인 MVC에서 말하는 Model이 아니다. 그런데, 웹에서는 이 방식이 더 간편하기 때문에 이 방식이 더 널리 퍼지면서 MVC의 Model이 비즈니스 엔티티를 일컫는 말로 바뀌기 시작했다.
그럼 고전적인 MVC는 어떤가? 다음과 같은 식이다.
def on_products_button_click():
model = find_view_by_id('products').model
for product in Product.objects.all():
model.append([prodcut.name, product.price])
model.notify_changed()
이런 방식은 자바의 swing이나 awt에서 테이블, 리스트 등의 뷰를 보면 알 수 있다. 안드로이드의 ListView - ListAdapter도 고전적인 MVC의 View-Model 관계에 가깝다. iOS의 UITableView와 UITableViewDataSource의 관계도 View-Model 관계다. 근데 ListAdapter든 UITableViewDataSource든 그 자체가 비즈니스 엔티티인 게 아니라 별도의 비즈니스 엔티티는 따로 있다. 그건 MVC의 Model은 아닌 거다.
근데 angular는 다음과 같은 식이다.
고전적인 MVC에서는 ListView와 ListModel이 연결되어 있고, ListModel은 ListView에 뿌려주기 위한 형태로 설계되어 있다. 그러면 Controller에서는 Product 객체의 값들을 바로 ListView에 넣는 게 아니라 ListModel에 값을 쓴다.